package com.yayako.security.authentication;

import com.alibaba.fastjson.JSONObject;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;

public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
  @Override
  protected void doFilterInternal(
      HttpServletRequest httpServletRequest,
      HttpServletResponse httpServletResponse,
      FilterChain filterChain)
      throws ServletException, IOException {
    String authHeader = httpServletRequest.getHeader("Authorization");
    if (authHeader != null) {
      Claims claims =
          Jwts.parser()
              .setSigningKey("MyJWT")
              .parseClaimsJws(authHeader.replace("Mrain", ""))
              .getBody();
      Date claimsExpiration = claims.getExpiration();
      logger.info("过期时间" + claimsExpiration);
      // 判断是否过期
      Date now = new Date();
      if (now.getTime() > claimsExpiration.getTime()) {
        throw new AuthenticationServiceException("凭证已过期，请重新登录！");
      }
      // 获取保存在token中的登录认证成功的authentication，
      // 利用UsernamePasswordAuthenticationToken生成新的authentication
      // 放入到SecurityContextHolder，表示认证通过
      Object tokenInfo = claims.get("authentication");
      // 通过com.alibaba.fastjson将其在转换。
      Authentication tokenAuthentication =
          JSONObject.parseObject(JSONObject.toJSONString(tokenInfo), Authentication.class);
      UsernamePasswordAuthenticationToken authentication =
          new UsernamePasswordAuthenticationToken(
              tokenAuthentication.getPrincipal(), null, tokenAuthentication.getAuthorities());
      SecurityContextHolder.getContext().setAuthentication(authentication);
    }
    filterChain.doFilter(httpServletRequest, httpServletResponse);
  }
}
